#!/data/data/com.termux/files/usr/bin/bash -e

VERSION=20250525
BASE_URL=https://kali.download/nethunter-images/current/rootfs
USERNAME=kali

RED='\033[1;31m'
MAGENTA='\033[1;95m'
PURPLE='\033[1;35m'
BLUE='\033[1;94m'
LIGHT_BLUE='\033[1;36m'
CYAN='\033[1;96m'
GREEN='\033[1;92m'
YELLOW='\033[1;93m'
RESET='\033[0m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
MAGENTA='\033[1;35m'
CYAN='\033[1;36m'
NC='\033[0m' 

GREEN='\033[1;92m'
BLUE='\033[1;94m'
PURPLE='\033[1;95m'
CYAN='\033[1;96m'
YELLOW='\033[1;93m'
RED='\033[1;91m'
ORANGE='\033[1;38;5;214m'
NC='\033[0m'
BOLD='\033[1m'


TERM_WIDTH=$(stty size | awk '{print $2}')
TERM_HEIGHT=$(stty size | awk '{print $1}')

if [ $TERM_WIDTH -lt 70 ]; then
  COLUMN_WIDTH=65
  PADDING=2
elif [ $TERM_WIDTH -lt 85 ]; then
  COLUMN_WIDTH=75
  PADDING=3
else
  COLUMN_WIDTH=85
  PADDING=5
fi

log() {
    case "$1" in
        "INFO")
            echo -e "${BLUE}[信息]${NC} $2"
            ;;
        "WARN")
            echo -e "${YELLOW}[警告]${NC} $2"
            ;;
        "ERROR")
            echo -e "${RED}[错误]${NC} $2"
            ;;
        *)
            echo -e "${CYAN}[调试]${NC} $2"
            ;;
    esac
}

error_exit() {
    log "ERROR" "$1"
    exit 1
}

command_exists() {
    command -v "$1" >/dev/null 2>&1
}

function unsupported_arch() {
    error_exit "不支持的架构: $(getprop ro.product.cpu.abi)"
}

function ask() {
    while true; do
        if [ "${2:-}" = "Y" ]; then
            prompt="Y/n"
            default=Y
        elif [ "${2:-}" = "N" ]; then
            prompt="y/N"
            default=N
        else
            prompt="y/n"
            default=
        fi

        printf "${CYAN}\n[?] "
        read -p "$1 [$prompt] " REPLY
        printf "${NC}"

        if [ -z "$REPLY" ]; then
            REPLY=$default
        fi

        case "$REPLY" in
            Y*|y*) return 0 ;;
            N*|n*) return 1 ;;
        esac
    done
}

function get_arch() {
    log "INFO" "检查设备架构..."
    case $(getprop ro.product.cpu.abi) in
        arm64-v8a)
            SYS_ARCH=arm64
            log "INFO" "检测到架构: ARM64"
            ;;
        armeabi|armeabi-v7a)
            SYS_ARCH=armhf
            log "INFO" "检测到架构: ARMhf"
            ;;
        *)
            unsupported_arch
            ;;
    esac
}

function set_strings() {
    
    wimg="full"
    
    if [[ ${SYS_ARCH} == "arm64" ]]; then
        log "INFO" "选择了: kali linux ARM64 (完整版 - 2.1 GiB)"
    elif [[ ${SYS_ARCH} == "armhf" ]]; then
        log "INFO" "选择了: kali linux ARMhf (完整版 - 2.0 GiB)"
    fi

    CHROOT=kali-${SYS_ARCH}
    IMAGE_NAME=kali-nethunter-rootfs-${wimg}-${SYS_ARCH}.tar.xz
}

function prepare_fs() {
    unset KEEP_CHROOT
    if [ -d "${CHROOT}" ]; then
        if ask "找到现有的 rootfs 目录 (${CHROOT})。是否删除并创建新的？" "N"; then
            log "INFO" "删除现有的 rootfs 目录..."
            rm -rf "${CHROOT}" || error_exit "无法删除现有目录"
        else
            KEEP_CHROOT=1
            log "INFO" "保留现有的 rootfs 目录"
        fi
    fi
} 

function cleanup() {
    if [ -f "${IMAGE_NAME}" ]; then
        if ask "是否删除已下载的 ${IMAGE_NAME} 文件？" "Y"; then
            log "INFO" "删除下载的镜像文件..."
            rm -f "${IMAGE_NAME}" || log "WARN" "无法删除文件: ${IMAGE_NAME}"
        fi
    fi
} 

function check_dependencies() {
    log "INFO" "检查并安装依赖包..."
    
    
    if [ ! -f "$PREFIX/etc/apt/sources.list.bak" ]; then
        cp "$PREFIX/etc/apt/sources.list" "$PREFIX/etc/apt/sources.list.bak"
    fi
    
   
    if ! grep -q "mirrors.tuna.tsinghua.edu.cn" "$PREFIX/etc/apt/sources.list"; then
        log "INFO" "更新软件源到清华镜像..."
        sed -i 's@^\(deb.*stable main\)$@#\1\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/termux-packages-24 stable main@' "$PREFIX/etc/apt/sources.list"
    fi
    
    # 更新包索引
    log "INFO" "更新包索引..."
    apt update -y &>/dev/null || apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" dist-upgrade -y &>/dev/null

    local required_packages=("proot" "tar" "wget" "xz")
    local missing_packages=()
    
    # 检查缺失的包
    for package in "${required_packages[@]}"; do
        if ! command_exists "$package"; then
            missing_packages+=("$package")
        else
            log "INFO" "$package 已就绪"
        fi
    done
    
    # 单独检查 aria2
    if ! command_exists "aria2c"; then
        missing_packages+=("aria2")
    else
        log "INFO" "aria2 已就绪"
    fi
    
    # 安装缺失的包
    if [ ${#missing_packages[@]} -gt 0 ]; then
        log "INFO" "安装缺失的包: ${missing_packages[*]}"
        for package in "${missing_packages[@]}"; do
            log "INFO" "正在安装 $package..."
            apt install -y "$package" || error_exit "无法安装 $package"
        done
    fi
    
    log "INFO" "升级已安装的包..."
    apt upgrade -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" &>/dev/null || log "WARN" "包升级过程中出现问题"
}

function get_rootfs() {
    unset KEEP_IMAGE
    if [ -f "${IMAGE_NAME}" ]; then
        if ask "找到现有的 ${IMAGE_NAME} 文件。是否删除并重新下载？" "N"; then
            rm -f "${IMAGE_NAME}" || error_exit "无法删除现有文件"
        else
            log "INFO" "使用现有的 rootfs 归档文件"
            KEEP_IMAGE=1
            return
        fi
    fi
    
    log "INFO" "开始下载 rootfs..."
    ROOTFS_URL="${BASE_URL}/${IMAGE_NAME}"
    if ask "是否使用多线程下载更快" "Y"; then
        if command_exists aria2c; then
            log "INFO" "使用多线程下载: ${ROOTFS_URL}"
            aria2c -x 16 -s 16 -k 1M "${ROOTFS_URL}" || error_exit "下载失败"
        else
            log "WARN" "未发现多线程使用wget下载: ${ROOTFS_URL}"
            wget -c "${ROOTFS_URL}" --progress=bar:force 2>&1 | while read -r line; do
                if [[ "$line" == *%* ]]; then
                    echo -ne "\r${BLUE}[下载]${NC} $line"
                fi
            done
        fi
    else
        log "INFO" "使用 wget 下载: ${ROOTFS_URL}"
        wget -c "${ROOTFS_URL}" --progress=bar:force 2>&1 | while read -r line; do
            if [[ "$line" == *%* ]]; then
                echo -ne "\r${BLUE}[下载]${NC} $line"
            fi
        done
    fi
    
    # 验证文件是否下载成功
    if [ ! -f "${IMAGE_NAME}" ]; then
        rm -f *.tar.xz.*
        error_exit "下载失败: ${IMAGE_NAME} 文件不存在"
    fi
    
    log "SUCCESS" "rootfs 下载完成"
}

function verify_sha() {
    log "INFO" "开始下载 rootfs 验证文件..."
    wget -q -c "${BASE_URL}/SHA256SUMS" -O SHA256SUMS

    if [ -f "SHA256SUMS" ]; then
        FILE_NAME=$(basename "$IMAGE_NAME")
        log "INFO" "提取文件名: $FILE_NAME"

        MATCH_PATTERN=$(echo "$FILE_NAME" | sed 's/kali-nethunter-/kali-nethunter-[0-9.]*-/')
        EXPECTED_HASH=$(grep -E " ${MATCH_PATTERN}$" SHA256SUMS | awk '{print $1}')

        if [ -z "$EXPECTED_HASH" ]; then
            error_exit "无法从 SHA256SUMS 中找到对应的 (模式: $MATCH_PATTERN)"
        fi

        log "INFO" "计算 SHA-256 ..."
        ACTUAL_HASH=$(sha256sum "$IMAGE_NAME" | awk '{print $1}')

        printf "预期: %s\n" "$EXPECTED_HASH"
        printf "真实: %s\n" "$ACTUAL_HASH"

        if [ "$EXPECTED_HASH" = "$ACTUAL_HASH" ]; then
            log "SUCCESS" "Rootfs SHA-256 验证通过"
            return 0
        else
            error_exit "Rootfs 文件已损坏或版本不匹配，请重新下载"
        fi
    else
        log "WARN" "未找到验证文件，跳过验证"
        return 0
    fi
}

function extract_rootfs() {
    if [ -z "$KEEP_CHROOT" ]; then
        log "INFO" "开始解压 耐心等待15至30分钟 rootfs..."

        
        xz -dc --verbose "$IMAGE_NAME" | proot --link2symlink tar -xf - \
            --no-same-owner --no-same-permissions --exclude='dev/*' 2>/dev/null || {
            error_exit "解压失败，请检查镜像文件是否完整"
        }

        log "SUCCESS" "rootfs 解压完成"
    else
        log "INFO" "使用现有的 rootfs 目录"
    fi
}

function create_launcher() {
    log "INFO" "创建启动器脚本..."
    
    NH_LAUNCHER=${PREFIX}/bin/nethunter
    NH_SHORTCUT=${PREFIX}/bin/nh
    
    cat > "$NH_LAUNCHER" <<- EOF
#!/data/data/com.termux/files/usr/bin/bash -e
cd \${HOME}
unset LD_PRELOAD

if [ ! -f $CHROOT/root/.version ]; then
    touch $CHROOT/root/.version
fi

user="$USERNAME"
home="/home/\$user"
start="sudo -u kali /bin/bash"

if grep -q "kali" ${CHROOT}/etc/passwd; then
    KALIUSR="1";
else
    KALIUSR="0";
fi

if [[ \$KALIUSR == "0" || ("\$#" != "0" && ("\$1" == "-r" || "\$1" == "-R")) ]];then
    user="root"
    home="/\$user"
    start="/bin/bash --login"
    if [[ "\$#" != "0" && ("\$1" == "-r" || "\$1" == "-R") ]];then
        shift
    fi
fi

cmdline="proot \\
        --link2symlink \\
        -0 \\
        -r $CHROOT \\
        -b /dev \\
        -b /proc \\
        -b /sdcard \\
        -b $CHROOT\$home:/dev/shm \\
        -w \$home \\
           /usr/bin/env -i \\
           HOME=\$home \\
           PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin \\
           TERM=\$TERM \\
           LANG=C.UTF-8 \\
           \$start"

cmd="\$@"
if [ "\$#" == "0" ];then
    exec \$cmdline
else
    \$cmdline -c "\$cmd"
fi
EOF
    chmod 700 "$NH_LAUNCHER"
    
    # 创建快捷方式
    if [ -L "${NH_SHORTCUT}" ]; then
        rm -f "${NH_SHORTCUT}"
    fi
    if [ ! -f "${NH_SHORTCUT}" ]; then
        ln -s "${NH_LAUNCHER}" "${NH_SHORTCUT}" >/dev/null
    fi
    
    log "SUCCESS" "启动器创建完成"
}

function create_kex_launcher() {
    log "INFO" "创建 KeX 启动器..."
    KEX_LAUNCHER=${CHROOT}/usr/bin/kex
    cat > $KEX_LAUNCHER <<- EOF
#!/bin/bash

function start-kex() {
    export FONTCONFIG_PATH=/etc/fonts
    export FONTCONFIG_FILE=/etc/fonts/fonts.conf
    if [ ! -f ~/.vnc/passwd ]; then
        passwd-kex
    fi
    USR=\$(whoami)
    if [ \$USR == "root" ]; then
        SCREEN=":2"
    else
        SCREEN=":1"
    fi 
    export MOZ_FAKE_NO_SANDBOX=1; export HOME=\${HOME}; export USER=\${USR}; LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgcc_s.so.1 nohup vncserver \$SCREEN >/dev/null 2>&1 </dev/null
    starting_kex=1
    return 0
}

function stop-kex() {
    rm -f /tmp/.X*-lock
    rm -f /tmp/.X11-unix/X*
    vncserver -kill :1 | sed s/"Xtigervnc"/"NetHunter KeX"/
    vncserver -kill :2 | sed s/"Xtigervnc"/"NetHunter KeX"/
    return $?
}

function passwd-kex() {
    vncpasswd
    return $?
}

function status-kex() {
    sessions=\$(vncserver -list | sed s/"TigerVNC"/"NetHunter KeX"/)
    if [[ \$sessions == *"590"* ]]; then
        printf "\n\${sessions}\n"
        printf "\n你可以使用 KeX 客户端连接这些显示器。\n\n"
    else
        if [ ! -z \$starting_kex ]; then
            printf '\n启动 KeX 服务器时出错。\n请尝试 "nethunter kex kill" 或重启 termux 会话并重试。\n\n'
        fi
    fi
    return 0
}

function kill-kex() {
    pkill Xtigervnc
    return \$?
}

case \$1 in
    start)
        start-kex
        ;;
    stop)
        stop-kex
        ;;
    status)
        status-kex
        ;;
    passwd)
        passwd-kex
        ;;
    kill)
        kill-kex
        ;;
    *)
        stop-kex
        start-kex
        status-kex
        ;;
esac
EOF

    chmod 700 $KEX_LAUNCHER
    log "SUCCESS" "KeX 启动器创建完成"
}

function fix_profile_bash() {
    log "INFO" "修复 bash profile..."
    if [ -f ${CHROOT}/root/.bash_profile ]; then
        sed -i '/if/,/fi/d' "${CHROOT}/root/.bash_profile"
    fi
}

function fix_resolv_conf() {
    log "INFO" "配置 DNS 解析..."
    
    resolv_conf="$CHROOT/etc/resolv.conf"
    cat > "$resolv_conf" <<EOF
nameserver 9.9.9.9
nameserver 149.112.112.112
nameserver 8.8.8.8
nameserver 114.114.114.114
EOF

    log "SUCCESS" "DNS 配置已完成"
}

function fix_sudo() {
    log "INFO" "配置 sudo 权限..."
    
    chmod +s "$CHROOT/usr/bin/sudo" || log "WARN" "无法设置 sudo 权限"
    chmod +s "$CHROOT/usr/bin/su" || log "WARN" "无法设置 su 权限"
    echo "kali    ALL=(ALL:ALL) ALL" > $CHROOT/etc/sudoers.d/kali
    echo "Set disable_coredump false" > $CHROOT/etc/sudo.conf
    
    log "SUCCESS" "sudo 权限配置完成"
}

function fix_uid() {
    log "INFO" "修复用户 ID 映射..."
    USRID=$(id -u)
    GRPID=$(id -g)
    nh -r usermod -u "$USRID" kali 2>/dev/null || log "WARN" "无法修改用户 ID"
    nh -r groupmod -g "$GRPID" kali 2>/dev/null || log "WARN" "无法修改用户 ID" 
    log "SUCCESS" "用户 ID 映射完成"
}

function update_sources_list() {
    log "INFO" "更新 Kali 软件源..."
    
    sources_list="$CHROOT/etc/apt/sources.list"
    if [ -f "$sources_list" ]; then
        cp "$sources_list" "$sources_list.backup"
        sed -i "s@http://http.kali.org/kali@https://mirrors.tuna.tsinghua.edu.cn/kali@g" "$sources_list"
        log "SUCCESS" "Kali 软件源已更新为清华镜像"
    else
        log "WARN" "未找到 Kali sources.list 文件"
    fi
}

function setup_chinese_support() {
    log "INFO" "开始配置中文支持..."
    
    # 安装中文字体和中文语言包
    nh -r apt-get update -y
    nh -r apt-get install -y locales fonts-wqy-microhei ttf-wqy-zenhei xfonts-intl-chinese
    
    # 配置中文环境
    nh -r bash -c "echo 'zh_CN.UTF-8 UTF-8' >> /etc/locale.gen"
    nh -r bash -c "echo 'zh_CN.GBK GBK' >> /etc/locale.gen"
    nh -r locale-gen
    
    # 设置默认语言为中文
    nh -r bash -c "echo 'LANG=zh_CN.UTF-8' > /etc/default/locale"
    nh -r bash -c "echo 'LC_ALL=zh_CN.UTF-8' >> /etc/default/locale"
    
    # 设置时区为上海
    nh -r ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    
    log "SUCCESS" "中文支持配置完成"
}

function setup_vnc_password() {
    log "INFO" "设置VNC初始密码为123456..."
    
    # 为kali用户设置VNC密码
    nh -r mkdir -p /home/kali/.vnc
    echo -e "123456\n123456\nn\n" | nh -r sudo -u kali vncpasswd
    nh -r chown -R kali:kali /home/kali/.vnc
    nh -r chmod 600 /home/kali/.vnc/passwd
    
    # 为root用户设置VNC密码
    nh -r mkdir -p /root/.vnc
    echo -e "123456\n123456\nn\n" | nh -r vncpasswd
    nh -r chmod 600 /root/.vnc/passwd
    
    log "SUCCESS" "VNC密码已设置为123456"
}

function get_ip_address() {
    IP=$(ip route get 1 2>/dev/null | awk '{print $7}' | head -n 1)
    if [ -z "$IP" ]; then
        IP="无法获取"
    fi
    echo -e "IP地址: ${GREEN}$IP${NC}"
}

function print_banner() {
    clear
    

# 打印CaiCai横幅 - 使用紫红色系
echo -e "${MAGENTA}"
echo "  ██████╗ █████╗ ██╗ ██████╗ █████╗ ██╗"
echo " ██╔════╝██╔══██╗██║██╔════╝██╔══██╗██║"
echo -e "${PURPLE} ██║     ███████║██║██║     ███████║██║"
echo " ██║     ██╔══██║██║██║     ██╔══██║██║"
echo -e "${BLUE} ╚██████╗██║  ██║██║╚██████╗██║  ██║██║"
echo "  ╚═════╝╚═╝  ╚═╝╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝"

# 打印分隔线
echo -e "${LIGHT_BLUE}"
echo " ✦・・・・・✦・・・・・✦・・・・・✦・・・・・✦"

# 打印Kali横幅 - 使用蓝色系
echo -e "${BLUE}"
echo " ██╗  ██╗ █████╗ ██╗     ██╗"
echo " ██║ ██╔╝██╔══██╗██║     ██║"
echo -e "${LIGHT_BLUE} █████╔╝ ███████║██║     ██║"
echo " ██╔═██╗ ██╔══██║██║     ██║"
echo -e "${CYAN} ██║  ██╗██║  ██║███████╗██║"
echo " ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝╚═╝"
echo -e "${CYAN}"
    echo " ════════════════════════════════════════"
    echo "                  Kali linux"
    echo "        专为移动设备优化的渗透测试平台"
    echo " ════════════════════════════════════════"
    echo -e "${GREEN}"
   
    
    
   
    echo -e "${GREEN}╔════════════════════════════════════════╗"
echo -e "║          ✦财财IT团队技术支持✦          ║"
echo -e "╚════════════════════════════════════════╝${RESET}"
echo -e "${NC}"

    # 显示系统信息
    echo -e "${YELLOW}[系统信息]${NC}"
    echo -e "设备型号: ${GREEN}$(getprop ro.product.model)${NC}"
    echo -e "安卓版本: ${GREEN}$(getprop ro.build.version.release)${NC}"
    echo -e "系统架构: ${GREEN}$(getprop ro.product.cpu.abi)${NC}"
    
    # 显示内存信息
    total_mem=$(grep MemTotal /proc/meminfo 2>/dev/null | awk '{print $2}')
    if [ -n "$total_mem" ]; then
        total_mem=$((total_mem / 1024))
        echo -e "内存大小: ${GREEN}${total_mem} MB${NC}"
    else
        echo -e "内存大小: ${GREEN}未知${NC}"
    fi
    
    # 显示IP地址
    get_ip_address
    
    echo -e "${RED}免责声明: 本工具仅用于教育目的，请勿用于非法用途${NC}"
    echo
}

function main() {
    
    cd "$HOME"
    
   
    print_banner
    get_arch
    set_strings
    prepare_fs
    check_dependencies
    get_rootfs
    verify_sha
    extract_rootfs
    create_launcher
    cleanup
    
    log "INFO" "为 Termux 配置 NetHunter..."
    fix_profile_bash
    fix_resolv_conf
    fix_sudo
    create_kex_launcher
    fix_uid
    update_sources_list
    
    
    log "INFO" "配置中文支持和VNC密码..."
    setup_chinese_support
    setup_vnc_password
    
    sleep 3
    
    
    print_banner
    echo
echo -e "${GREEN}"
printf "%-${TERM_WIDTH}s" | tr ' ' '='
echo
echo "     🎯Kali linux 安装完成!" | awk '{printf "%*s\n", (length($0)+TERM_WIDTH)/2, $0}' TERM_WIDTH=$TERM_WIDTH
printf "%-${TERM_WIDTH}s" | tr ' ' '='
echo -e "${NC}\n"
    echo -e "${GREEN}"
    echo
    echo -e "${GREEN}╔════════════════════════════════════════╗"
echo -e "║           ✦📟 命令使用说✦                ║"
echo -e "╚════════════════════════════════════════╝${RESET}"
    echo -e "${GREEN}   nh                快速启动 kali linux${NC}"
    echo -e "${GREEN}   nh -r             以 root 身份启动${NC}"
    echo -e "${GREEN}   exit               在 kali linux 中退出${NC}"
    echo
        echo -e "${GREEN}╔════════════════════════════════════════╗"
echo -e "║           ✦🌐 vnc 图形设置✦            ║"
echo -e "╚════════════════════════════════════════╝${RESET}"
    echo -e "${GREEN}  kex passwd       修改 vnc 密码${NC}"
    echo -e "${GREEN}    kex &         启动图形界面${NC}"
    echo -e "${GREEN}   kex stop      停止图形界面${NC}"
    echo -e "${GREEN}   kex status    查看状态${NC}"
    echo
    echo -e "${GREEN}╔════════════════════════════════════════╗"
echo -e "║           ✦🖥️vnc连接地址和密码✦         ║"
echo -e "╚════════════════════════════════════════╝${RESET}"
    echo -e "${GREEN}   连接地址: localhost:5901（普通用户）${NC}"
    echo -e "${GREEN}   连接地址: localhost:5902（root用户）${NC}"
    echo -e "${GREEN}   初始密码：123456（默认密码）${NC}"
    echo -e 

echo -e "${PURPLE}════════════════════════════════════════════════${NC}"
echo -e " kali linux 定制版 ${BOLD}by 财财IT${NC}"
echo -e " 技术支持: ${UNDERLINE}tech@cai-cai.it${NC} | $(date +'%Y.%m.%d %H:%M')"
echo -e "${PURPLE}════════════════════════════════════════════════${NC}"

echo -e "\n${YELLOW}💡 提示: ${NC}输入 ${GREEN}nh${NC} 立即开始渗透测试之旅！"
echo -e "\n${YELLOW}💡 提示: ${NC}再次输入 ${GREEN}kex &${NC} 立即开启图形化"
}

main "$@"